import java.util.ArrayList;

/**
 * Ez az objektum tartalmazza a játék belépési pontját, az állapotváltozóit,
 * ez tölti be a pályákat, lép át a következő pályára, kezeli az öletek számát.
 * Továbbá fogadja a mozgás illetve bombalerakás parancsokat.
 */
public class Game
{
  Entity _unnamed_Entity_;
  private ArrayList _fields = new ArrayList();
  private Timer _timer;
  private Player juzkez;
  public Integer ID = SkeletonHelper.GetObjectID();


  /**
   * A program belépési pontja.
   * @param args
   */
  public static void main(String[] args)
  {
    SkeletonHelper.FunctionBegin(-1, "static Game", "main");
    Game game = new Game();
    game.init();
    game.startBoard();
    SkeletonHelper.FunctionEnd(-1, "static Game", "main");
  }

  /**
   * Itt lesz majd inicializálva a játék.
   */
  public void init()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "init");

    SkeletonHelper.FunctionEnd(ID, "Game", "init");
  }

  /**
   * lépteti a játékost egy adott irányba.
   * @param direction A lépés iránya.
   */
  public void step(int direction)
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "step");

    juzkez.move(direction, 1);

    SkeletonHelper.FunctionEnd(ID, "Game", "step");
  }

  /**
   * alaphelyzetbe állítja a pályát.
   */
  public void reset()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "reset");

    SkeletonHelper.WriteLogLine("TODO");

    SkeletonHelper.FunctionEnd(ID, "Game", "reset");
  }

  /**
   * Szünetelteti a játékot.
   */
  public void pause()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "pause");

    SkeletonHelper.WriteLogLine("TODO");

    SkeletonHelper.FunctionEnd(ID, "Game", "pause");
  }

  /**
   * A skeletonban: kezeli a menüt, betölti a választott pályát.
   * A játékban csak a pálya elindítása lesz a feladata.
   */
  public void startBoard()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "startBoard");

    String level = SkeletonHelper.Ask("Melyik pályát töltsem?", 
            "(0) lépés teszt, jobbra\r\n" +
            "(1) ásás teszt, lefelé\r\n" +
            "(2) szikla eltolás teszt, balra\r\n" +
            "(3) gyémánt felszedés, jobbra\r\n" +
            "(4) bomba lerakás\r\n" +
            "(5) kilépés egy pályáról a kijáraton.\r\n" +
            "(6) bomba robbanás\r\n" +
            "(7) JuzKez halála\r\n" +
            "(8) szaporodó szörny felrobbanása\r\n" +
            "(9) kilépés");
    int i = Integer.decode(level);
    SkeletonHelper.WriteLogLine("Töltöm a " + level + ". pályát...");

    switch (i)
    {
      case 0:
        /**
         * Lépés
         */
      {
        //teszt inicializálása
        Field jkField = new Field(this);
        juzkez = new Player();
        jkField.add(juzkez);
        Field emptyField = new Field(this);
        jkField.setNeighbour(1, emptyField);
        emptyField.setNeighbour(3, jkField);

        //teszt futtatása
        SkeletonHelper.WriteLogLine("Futtatom a tesztet:");
        this.step(1);

        break;
      }
      case 1:
        /**
         * homok kiásása
         */
      {
        //teszt inicializálása
        Field jkField = new Field(this);
        juzkez = new Player();
        jkField.add(juzkez);
        Field sandField = new Field(this);
        sandField.add(new Sandstone());
        jkField.setNeighbour(2, sandField);
        sandField.setNeighbour(0, jkField);

        SkeletonHelper.WriteLogLine("Futtatom a tesztet:");
        this.step(2);

        break;
      }
      case 2:
        /**
         * szikla eltolása
         */
      {
        //teszt inicializálása
        Field jkField = new Field(this);
        juzkez = new Player();
        jkField.add(juzkez);
        Field boulderField = new Field(this);
        boulderField.add(new Boulder());
        jkField.setNeighbour(3, boulderField);
        boulderField.setNeighbour(1, jkField);
        Field emptyField = new Field(this);
        emptyField.setNeighbour(1, boulderField);
        boulderField.setNeighbour(3, emptyField);

        SkeletonHelper.WriteLogLine("Futtatom a tesztet:");
        this.step(3);


        break;
      }
      case 3:
        /**
         * gyémánt felszedése
         */
      {
        //teszt inicializálása
        Field jkField = new Field(this);
        juzkez = new Player();
        jkField.add(juzkez);
        Field gemField = new Field(this);
        gemField.add(new Diamond());
        gemField.setNeighbour(3, jkField);
        jkField.setNeighbour(1, gemField);

        SkeletonHelper.WriteLogLine("Futtatom a tesztet:");
        this.step(1);

        break;
      }
      case 4:
        /**
         * bomba lerakása
         */
      {
        //teszt inicializálása
        Field jkField = new Field(this);
        juzkez = new Player();
        jkField.add(juzkez);

        Field emptyField = new Field(this);
        emptyField.setNeighbour(3, jkField);
        jkField.setNeighbour(1, emptyField);

        SkeletonHelper.WriteLogLine("Futtatom a tesztet:");
        this.setBomb();
        this.step(1);
        break;
      }
      case 5:
        /**
         * kilépés a kijáraton
         */
      {
        //teszt inicializálása
        Field jkField = new Field(this);
        juzkez = new Player();
        jkField.add(juzkez);
        Field exitField = new Field(this);
        exitField.add(new Exit());
        exitField.setNeighbour(3, jkField);
        jkField.setNeighbour(1, exitField);

        SkeletonHelper.WriteLogLine("Futtatom a tesztet:");
        this.step(1);

        break;
      }
      case 6:
        /**
         * bomba robbanás
         */
      {
        //teszt inicializálása
        Field fc = new Field(this);
        Field ft = new Field(this); fc.setNeighbour(0, ft);
        Field fl = new Field(this); fc.setNeighbour(1, fl);
        Field fb = new Field(this); fc.setNeighbour(2, fb);
        Field fr = new Field(this); fc.setNeighbour(3, fr);

        Bomb b = new Bomb();
        fc.add(b);
        ft.add(new Sandstone());
        fl.add(new Gemster());
        fb.add(new Wall());
        fr.add(new Granite());

        SkeletonHelper.WriteLogLine("Futtatom a tesztet:");
        b.explode();

        break;
      }
      case 7:
        /**
         * JuzKez halála
         */
      {
        Field jkField = new Field(this);
        jkField.add(juzkez = new Player());

        SkeletonHelper.WriteLogLine("Futtatom a tesztet:");
        juzkez.kill();
      }
      case 8:
        /**
         * szaporodó szörny robbanása
         */
      {
        Field fl = new Field(this);
        Field fr = new Field(this);fr.setNeighbour(3, fl); fl.setNeighbour(1, fr);
        Field fll = new Field(this);fl.setNeighbour(3, fll);
        Field flt = new Field(this);fl.setNeighbour(0, flt);
        Field flb = new Field(this);fl.setNeighbour(2, flb);
        Field frr = new Field(this);fr.setNeighbour(1, frr);
        Field frt = new Field(this);fr.setNeighbour(0, frt);
        Field frb = new Field(this);fr.setNeighbour(2, frb);

        fl.add(new Multiplier());
        fr.add(new Multiplier());
        
        SkeletonHelper.WriteLogLine("Futtatom a tesztet:");
        fl.getEntity().explode();
      }
    }

    SkeletonHelper.FunctionEnd(ID, "Game", "startBoard");
  }

  /**
   * A következő pályára lép.
   * @return Igaz, ha volt pálya még.
   */
  public boolean nextLevel()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "nextLevel");

    SkeletonHelper.WriteLogLine("Ez a skeletonban nincs implementálva.");

    SkeletonHelper.FunctionEnd(ID, "Game", "nextLevel", "true");
    return true;
  }

  /**
   * Eggyel növeli a gyémántok számát.
   */
  public void addDiamond()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "addDiamond");

    SkeletonHelper.WriteLogLine("Felvettünk egy gyémántot.");

    SkeletonHelper.FunctionEnd(ID, "Game", "addDiamond");
  }

  /**
   * Megöli a játékost.
   */
  public void killPlayer()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "killPlayer");

    SkeletonHelper.WriteLogLine("JuzKez kinyírva.");

    SkeletonHelper.FunctionEnd(ID, "Game", "killPlayer");
  }

  /**
   * Letetet egy bombát JuzKezzel.
   */
  public void setBomb()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "setBomb");

    juzkez.setBomb();

    SkeletonHelper.FunctionEnd(ID, "Game", "setBomb");
  }

  /**
   * Létrehozza a Bomb osztály egy példányát, majd visszaadja a hívónak.
   * @return
   */
  public Bomb createBomb()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "createBomb");

    Bomb b = new Bomb();

    SkeletonHelper.FunctionEnd(ID, "Game", "createBomb", "[" + b.ID + "]");
    return b;
  }

  /**
   * Létrehozza a Diamond osztály egy példányát, majd visszaadja a hívónak.
   * @return
   */
  public Diamond createDiamond()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "createDiamond");

    Diamond d = new Diamond();

    SkeletonHelper.FunctionEnd(ID, "Game", "createDiamond", "[" + d.ID + "]");
    return d;
  }

  /**
   * Megnöveli a bombák hatósugarát.
   */
  public void increaseBombStrength()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "increaseBombStrength");

    SkeletonHelper.FunctionEnd(ID, "Game", "increaseBombStrength");
  }

  /**
   * Lerak egy darab uránt a pályára, egy szaporodó szörny halála esetén.
   */
  public void setUranium()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "setUranium");


    SkeletonHelper.FunctionEnd(ID, "Game", "setUranium");
  }

  /**
   * Visszaadja, hogy van-e a pályán urán.
   * @return
   */
  public boolean getUranium()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "getUranium");

    String a = SkeletonHelper.Ask("Adjunk uránt juzkeznek?", "(i)gen, (n)em");
    if (a.equals("i"))
      setUranium();
    
    SkeletonHelper.FunctionEnd(ID, "Game", "getUranium", "true");
    return a.equals("i");
  }

  /**
   * Visszaadja a Game osztály JuzKezt reprezentáló példányát.
   * @return JuzKez
   */
  public Player getPlayer()
  {
    SkeletonHelper.FunctionBegin(ID, "Game", "getPlayer");

    SkeletonHelper.FunctionEnd(ID, "Game", "getPlayer");
    return juzkez;
  }

  /**
   * Visszaadja az időzítőt.
   * @return
   */
  public Timer getTimer()
  {
    return _timer;
  }
}